import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:sports_new/controller/live/ali_live_logic.dart';
import 'package:sports_new/controller/live/qkd_player_logic.dart';
import 'package:sports_new/entity/live/live_detail_entity.dart';
import 'package:sports_new/entity/live/ali_live_message.dart';
import 'package:sports_new/server/ws/ali_im_manager.dart';
import 'package:sports_new/utils/ali_message.dart';
import 'package:sports_new/utils/gift_cache.dart';
import 'package:sports_new/utils/toast_utils.dart';
import 'package:sports_new/utils/utils.dart';
import 'package:sports_new/view/live/items/gift_effect_view.dart';
import 'package:sports_new/widgets/base/qkd_dialog.dart';
import '../../entity/live/live_chat_entity.dart';
import '../../entity/live/live_chat_info.dart';
import '../../entity/match/expert_views_entity.dart';
import '../../entity/other/user_info_entity.dart';
import '../../resources/colours.dart';
import '../../server/api/expert_api.dart';
import '../../server/api/live_api.dart';
import '../../server/api/user_api.dart';
import '../../utils/user.dart';
import '../../utils/widget_utils.dart';
import '../../view/live/items/live_message_list.dart';
import '../../widgets/circular.dart';
import '../../widgets/base/qkd_image.dart';
import '../../widgets/base/qkd_text.dart';
import '../../widgets/slide_transition_x.dart';

class LiveMessageLogic extends GetxController{
  LiveMessageLogic({required this.liveDetail,required this.scene});
  final MessageScene scene;
  LiveDetailEntity? liveDetail;
  LiveChatInfo? chatInfo;
  PlanEntity? plan;
  bool _showPlan = true;
  ScrollController scrollController = ScrollController();
  List<AliLiveMessage> messages = [];
  bool _inScroll = false;
  int _messageCount = 0;
  bool _showMessage = false;
  final Rx<String> _str = "".obs;
  final textController = TextEditingController();
  late FocusNode focus = FocusNode();
  UserInfoEntity? _userStore;
  List<AliLiveMessage> gifts = [];
  GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
  Timer? _giftTimer;
  bool _coverJoin = true;
  Timer? _joinTimer;

  bool get inScroll => _inScroll;
  int get messageCount => _messageCount;
  bool get showMessage => _showMessage;
  String get str => _str.value;
  bool get showPlan => _showPlan;
  UserInfoEntity? get userStore => _userStore;
  bool get coverJoin => _coverJoin;

  set coverJoin(bool value) {
    _coverJoin = value;
    update();
  }
  set userStore(UserInfoEntity? value) {
    _userStore = value;
    update();
  }
  set showPlan(bool value) {
    _showPlan = value;
    update();
  }
  set str(String value) {
    _str.value = value;
  }
  set showMessage(bool value) {
    _showMessage = value;
    if(value == false) messageCount = 0;
    update();
  }
  set messageCount(int value) {
    _messageCount = value;
    update();
  }
  set inScroll(bool value) {
    _inScroll = value;
    update();
  }

  @override
  void onInit() {
    AliMessage().enterGroup(liveDetail?.chatGroupId??"");
    _giftTimer = Timer.periodic(const Duration(seconds: 1), (timer) async{
      for (int i=0;i<gifts.length;i++) {
        if(gifts[i].showTime != null) {
          if (DateTime.now().difference(gifts[i].showTime!).inSeconds > 4){
            removeGift(i);
          }
        }
      }
    });
    focus.addListener(() {
      if(focus.hasFocus){
        update();
      }
      if(!focus.hasFocus){
        update();
      }
    });
    super.onInit();
  }

  @override
  void onReady() async{
    await getInfo();
    await getHistory();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      scrollToEnd();
    });
    AliMessage().messageResp().listen((event) async{
      AliLiveMessage? message;
      try{
        message = AliLiveMessage.fromJson(jsonDecode(event));
        AliImManager.recordAdd("收到消息:${message.toJson()}");
      }catch(e){
        Logger().d(e);
        AliImManager.recordAdd("收到消息 error:${e}");
      }
      if(message == null) return;
      switch(message.status){
        case MessageType.joinGroup:
          if(message.userName.hasValue) {
            coverJoin = false;
            if(!coverJoin) _joinTimer?.cancel();
            _joinTimer = Timer(
              const Duration(seconds: 5),
              () => coverJoin = true
            );
            if(messages.last.status == MessageType.joinGroup){
              messages.last = message;
            }else{
              messages.add(message);
            }
          }
          break;
        case MessageType.sendMessage:
          if(message.userName.hasValue) {
            handleMessage(message);
          }
          if(showMessage) messageCount += 1;
          break;
        case MessageType.gift:
          if(message.userName.hasValue) {
            handleMessage(message);
            int index = gifts.indexWhere((element) => element.giftName == message?.giftName && element.userId == message?.userId);
            if(index != -1) {
              gifts[index].count = (gifts[index].count??0)+(message.count??0);
              gifts[index].showTime = DateTime.now();
            }else{
              if(gifts.length == 2) removeGift(0);
              insertGift(message);
            }
            if(message.animateUrl.hasValue) {
              try {
                String path = await GiftCache.getPath(message.animateUrl!);
                GiftEffectController().play(path);
              }catch(e){
                Logger().d("GiftEffectError: $e");
              }
            }
            if(showMessage) messageCount += 1;
          }
          break;
        case MessageType.deleteMessage:
          messages.removeWhere(
            (element) => element.messageId == message?.messageId
          );
          if(showMessage) messageCount -= 1;
          break;
        case MessageType.mute:
          // TODO: Handle this case.
          break;
        case MessageType.muteAll:
          // TODO: Handle this case.
          break;
        case MessageType.cancelMute:
          // TODO: Handle this case.
          break;
        case MessageType.cancelMuteAll:
          // TODO: Handle this case.
          break;
        case MessageType.exitGroup:
          // TODO: Handle this case.
          break;
        case MessageType.announce:
          messages.add(message);
          break;
        case MessageType.focus:
          if(message.userName.hasValue) {
            handleMessage(message);
            if(showMessage) messageCount += 1;
          }
          break;
        case MessageType.other:
          handleMessage(message);
          if(showMessage) messageCount += 1;
          break;
        case MessageType.error:
          // TODO: Handle this case.
          break;
        case MessageType.completion:
          try {
            Get.find<QkdPlayerLogic>(
              tag: "${liveDetail?.liveId}"
            ).status = PlayStatus.completion;
          }catch(e){
            try{
              Get.find<QkdPlayerLogic>(
                  tag: "${liveDetail?.matchId}"
              ).status = PlayStatus.completion;
            }catch(e){
              Logger().d("complete error");
            }
            Logger().d("complete error");
          }
          break;
        default:
          break;
      }
      update();
      if(!showMessage) scrollToEnd();
    });
    super.onReady();
  }

  void handleMessage(AliLiveMessage message){
    if(!coverJoin){
      messages.insert(messages.length>1?messages.length-1:0, message);
    }else{
      if(messages.last.status == MessageType.joinGroup) {
        messages.removeLast();
      }
      messages.add(message);
    }
  }

  Future getInfo() async{
    chatInfo = await LiveApi.getChatInfo(liveDetail?.liveId);
    if(chatInfo?.noticeSystem.hasValue == true) {
      messages.add(AliLiveMessage(message: chatInfo?.noticeSystem,status: MessageType.announce));
    }
    if(chatInfo?.noticeRoom.hasValue == true){
      messages.add(AliLiveMessage(message: chatInfo?.noticeRoom,status: MessageType.announce));
    }
    try {
      var row = await ExpertApi.getLivePlan(
          "${liveDetail?.matchId}",
          liveDetail?.expertId,
          liveDetail?.sportsId ?? 1,
          1, 10
      );
      if (row.recommend.hasValue) {
        plan = row.recommend!.first;
      }
      // else if (row.other.hasValue) {
      //   plan = row.other!.first;
      // }
    }catch(e){
      Logger().d(e);
    }
    update();
  }

  Future getHistory() async{
    List<LiveChatEntity>? list = await LiveApi.getChatHistory(id: liveDetail?.liveId);
    List<AliLiveMessage>? history = list.map((e) => AliLiveMessage.fromChatMessage(e)).toList();
    messages.addAll(history);
    update();
  }

  Future muteUser(AliLiveMessage message) async{
    var check = await LiveApi.checkMuteUser(liveDetail?.liveId??0, message.userId??"");
    var result = await Get.dialog(
      QkdDialog.alert(
        check??false?"确定解除${message.userName??""}的禁言吗":"确定禁言${message.userName??""}吗",
        confirmText: check??false?"解除":"禁言",
      )
    );
    if(result == true){
      var back = await LiveApi.muteUser(liveDetail?.liveId??0, message.userId??"",check??false);
      if(back == true){
        ToastUtils.show("${check??false?"解禁":"禁言"}成功");
      }else{
        ToastUtils.show("${check??false?"解禁":"禁言"}失败");
      }
    }
  }

  Future deleteMessage(AliLiveMessage message) async{
    var result = await Get.dialog(
        QkdDialog.alert(
          "确定删除${message.userName??""}的评论吗",
          confirmText: "删除",
        )
    );
    if(result == true){
      var back = await LiveApi.deleteMessage((message.messageId??"").toInt()??0);
      if(back == true){
        ToastUtils.show("删除成功");
      }else{
        ToastUtils.show("删除失败");
      }
    }
  }

  Future sendChat({String? text}) async{
    await LiveApi.sendChat(text ?? str, liveDetail?.liveId);
  }

  @override
  void onClose() {
    AliMessage().leaveGroup(liveDetail?.chatGroupId??"",liveDetail?.liveId);
    _giftTimer?.cancel();
    super.onClose();
  }

  Future scrollToEnd({double? position}) async{
    if(inScroll) return;
    inScroll = true;
    await Future.delayed(const Duration(milliseconds: 200));
    await scrollController.animateTo(
        position ?? scrollController.position.maxScrollExtent,
        duration: const Duration(milliseconds: 200),
        curve: Curves.easeIn
    );
    messageCount = 0;
    inScroll = false;
    update();
  }

  Widget gift(int index,Animation<double> animation,{AliLiveMessage? msg}){
    AliLiveMessage entity = msg??gifts[index];
    Color red = scene == MessageScene.match?Colours.redFBAFBC:Colours.redFF748D;
    Color blue = scene == MessageScene.match?Colours.blueBADDF9:Colours.blue74C4FF;
    late Color bgColor = (entity.price??0)*(entity.count??0)>=20?red:blue;
    late List<Color> colors = [
      bgColor.withOpacity(scene == MessageScene.match?1:0.8),
      bgColor.withOpacity(0)
    ];
    List<double> stops = scene == MessageScene.match?[0.85,0.98]:[0.2,0.85];
    Color textColor = scene == MessageScene.match?Colours.text:Colours.white;
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(-1, 0), end: const Offset(0, 0)
      ).animate(animation),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Circular(
            width: 222,
            height: 36,
            margin: const EdgeInsets.only(left: 8,bottom: 4),
            borderRadius: const BorderRadius.horizontal(left: Radius.circular(36)),
            gradient: LinearGradient(
              colors: colors,
              stops: stops
            ),
            child: Row(
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(2, 2, 0, 2),
                  child: QkdImage(
                    imageUrl: entity.userAvatar??"",
                    width: 32,height: 32,
                    shape: BoxShape.circle,
                    fit: BoxFit.cover,
                    shimmer: false,
                  ),
                ),
                Container(width: 8),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Flexible(
                        child: QkdText(entity.userName??"",
                          fontSize: 12,
                          color: textColor,
                          fontWeight: FontWeight.w500,
                          maxLines: 1,
                        ),
                      ),
                      QkdText(entity.message??"",
                        fontSize: 10,
                        color: textColor.withOpacity(0.6),
                        maxLines: 1,
                      )
                    ],
                  ),
                ),
                Container(width: 8),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    QkdImage(
                      imageUrl: entity.giftLogo??"",
                      width: 36,height: 36,
                      fit: BoxFit.cover,
                      shimmer: false,
                    ),
                    Container(width: 3),
                    QkdText("x",
                      fontSize: 17,
                      fontFamily: "KingKong",
                      color: textColor
                    ),
                    AnimatedSwitcher(
                      duration: const Duration(milliseconds: 150),
                      transitionBuilder: (child, animation) =>
                        SlideTransitionX(
                          position: animation,
                          direction: AxisDirection.right,
                          child: child
                        ),
                      child: QkdText("${entity.count??1}",
                        key: ValueKey<int>(entity.count??1),
                        fontSize: 17,
                        fontFamily: "KingKong",
                        color: textColor
                      )
                    )
                  ],
                )
              ],
            ),
          ),
        ],
      ),
    );
  }

  void removeGift(int index){
    AliLiveMessage msg = gifts.removeAt(index);
    listKey.currentState?.removeItem(
      index, (context, animation) {
        return gift(index, animation,msg: msg);
      }
    );
    update();
  }

  void insertGift(AliLiveMessage message){
    message.showTime = DateTime.now();
    gifts.add(message);
    listKey.currentState?.insertItem(gifts.isEmpty?0:gifts.length-1);
    update();
  }

  Future toFocus() async{
    await User.needLogin(() {
      Utils.onEvent('liveroom_gift_follow');
      if(userStore?.id != User.info?.id) {
        AliMessage().enterGroup(
            liveDetail?.chatGroupId ?? ""
        );
        userStore = User.info;
      }
    });
    if (liveDetail?.isFocus == 0) {
      final result = await UserApi.focus(
          expertId: liveDetail?.expertId
      );
      if (result == 200) {
        LiveDetailEntity? entity = await LiveApi.getLiveDetail(liveDetail?.liveId);
        if(entity != null){
          liveDetail?.isFocus = entity.isFocus;
          ToastUtils.show('关注成功');
        }else{
          ToastUtils.show('关注失败');
        }
        update();
      }
    } else {
      final r = await WidgetUtils.alertQuery('确认不再关注？');
      if (r == true) {
        final result = await UserApi.unFocus(
            expertId: liveDetail?.expertId
        );
        if (result == 200) {
          LiveDetailEntity? entity = await LiveApi.getLiveDetail(liveDetail?.liveId);
          if(entity != null){
            liveDetail?.isFocus = entity.isFocus;
            ToastUtils.show('取关成功');
          }else{
            ToastUtils.show('取关失败');
          }
          update();
        }
      }
    }
  }
}